package com.CampaignManager.client;

import java.util.Date;

import com.CampaignManager.shared.CityDTO;
import com.CampaignManager.shared.JobDTO;
import com.CampaignManager.shared.PlayerDTO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;

public class AvailableJobsForm extends Composite {

	private static AvailableJobsFormUiBinder uiBinder = GWT.create(AvailableJobsFormUiBinder.class);
	interface AvailableJobsFormUiBinder extends UiBinder<Widget, AvailableJobsForm> {}

	private CampaignManager mainForm = null;
	private String cityName = null;
	private JobDTO job = null;
	private PlayerDTO playerInfo = null;
	
	public AvailableJobsForm(String cityName, CampaignManager mainForm, PlayerDTO playerInfo) {
		
		this.mainForm = mainForm;
		this.cityName = cityName;
		this.playerInfo = playerInfo;
				
		initWidget(uiBinder.createAndBindUi(this));
		
		this.lblTitle.setText("Available Jobs in "+cityName);
		
		for (CityDTO city : mainForm.Cities) {
			if (!cityName.equals(city.getName())) {
			
				LatLng start = MapUtils.GetCurrentLocation(playerInfo);
				LatLng end = city.GetLocation();
				double dist = start.distanceFrom(end);
				dist = dist * PlayerDTO.MILES_TO_LATLONG;
				
				double time = dist/PlayerDTO.MILES_PER_DAY;
				
				NumberFormat milefmt = NumberFormat.getFormat("0.00");
				NumberFormat goldfmt = NumberFormat.getFormat("0");
				
				double deliveryReward = dist * PlayerDTO.GOLD_PER_MILE_DELIVERY;
				String deliveryItem = city.getName()+"("+city.getFaction()+") Time:"+milefmt.format(time)+" Days, "+goldfmt.format(deliveryReward)+" Gold";
				this.deliveryCity.addItem(deliveryItem, goldfmt.format(deliveryReward));
				
				double excortReward = dist * PlayerDTO.GOLD_PER_MILE_ESCORT;
				String escortItem = city.getName()+"("+city.getFaction()+") Time:"+milefmt.format(time)+" Days, "+goldfmt.format(excortReward)+" Gold";
				this.escortCity.addItem(escortItem, goldfmt.format(excortReward));
			}
		}
		
		int ongoingJobs = 0;
		for (JobDTO job : playerInfo.getOngoingJobs()) {
			if (job.getJobFor().equals(cityName)) {
				ongoingJobs += 1;
			}
		}
		if (ongoingJobs > 0) {
			this.btnTakeDelivery.setEnabled(false);
			this.btnTakeDelivery.setTitle("Already doing a Job");
			this.btnTakeEscort.setEnabled(false);
			this.btnTakeEscort.setTitle("Already doing a Job");
			this.btnTakeBattle.setEnabled(false);
			this.btnTakeBattle.setTitle("Already doing a Job");
		} else if (playerInfo.getArmySize() < 5) {
			this.btnTakeEscort.setEnabled(false);
			this.btnTakeEscort.setTitle("Need Army Size of at least 5");
		}
		
		AddBattle(15L);
		AddBattle(25L);
		AddBattle(35L);
		AddBattle(50L);
		AddBattle(75L);
		AddBattle(100L);
	}
		
	private void AddBattle(Long size) {
		NumberFormat goldfmt = NumberFormat.getFormat("0");
		double reward = size * PlayerDTO.GOLD_PER_BATTLE_POINT;
		battleSize.addItem(size.toString()+" point Battle, "+goldfmt.format(reward)+" gold",size.toString());
	}
	
	@UiField
	Label lblTitle;

	@UiField
	ListBox deliveryCity;
	@UiField
	Button btnTakeDelivery;
	@UiHandler("btnTakeDelivery")
	void btnTakeDeliveryClick(ClickEvent event) {
		
		String itemDisplay = deliveryCity.getItemText(deliveryCity.getSelectedIndex());
		String itemValue = deliveryCity.getValue(deliveryCity.getSelectedIndex());
		
		job = new JobDTO();
		job.setJobType("Delivery");
		for (CityDTO city : mainForm.Cities) {
			if (itemDisplay.startsWith(city.getName()))
				job.setDestination(city.getName());
		}
		job.setReward(Long.parseLong(itemValue));
		
		DisplayJobDetails();
	}
	
	@UiField
	ListBox escortCity;
	@UiField
	Button btnTakeEscort;
	@UiHandler("btnTakeEscort")
	void btnTakeEscortClick(ClickEvent event) {
		
		String itemDisplay = escortCity.getItemText(escortCity.getSelectedIndex());
		String itemValue = escortCity.getValue(escortCity.getSelectedIndex());
		
		job = new JobDTO();
		job.setJobType("Escort");
		for (CityDTO city : mainForm.Cities) {
			if (itemDisplay.startsWith(city.getName()))
				job.setDestination(city.getName());
		}
		job.setReward(Long.parseLong(itemValue));
		DisplayJobDetails();
	}

	@UiField
	ListBox battleSize;
	@UiField
	Button btnTakeBattle;
	@UiHandler("btnTakeBattle")
	void btnTakeBattleClick(ClickEvent event) {
		
		String itemDisplay = battleSize.getItemText(battleSize.getSelectedIndex());
		String itemValue = battleSize.getValue(battleSize.getSelectedIndex());
		Long battleSizeValue = Long.parseLong(itemValue);
		
		if (battleSizeValue > playerInfo.getArmySize()) {
			if (!Window.confirm("Your current army is smaller than "+itemValue+", are you sure you want battle a larger army?")) {
				return;
			}
		}
		
		job = new JobDTO();
		job.setJobType("Battle");
		job.setDestination(itemDisplay);
		job.setReward(battleSizeValue);
		DisplayJobDetails();
	}
	
	@UiField
	Label jobDetail;
	
	@UiField
	HTML detailsHtml;
	@UiField
	HTML unavailableHtml;
	
	private void DisplayJobDetails() {
		
		job.setJobFor(cityName);
		jobDetail.setText(job.getJobDescription());

		mainForm.campaignService.CheckExistingPendingJob(new AsyncCallback<Boolean>() {
    		public void onFailure(Throwable error) {
    			mainForm.handleError(error);
			}
			public void onSuccess(Boolean result) {
				if (result) {
					String html = "<p>You already have a pending job.  You need to go to the <a href=https://groups.google.com/forum/#!newtopic/"+PlayerDTO.GROUP_NAME+" target=_blank>Group</a> and post a topic with the story for the last job before taking another one.</p>";
					unavailableHtml.setHTML(html);
					unavailableHtml.setVisible(true);
					detailsHtml.setVisible(false);
					btnFinish.setVisible(false);
				} else {
					unavailableHtml.setVisible(false);
					detailsHtml.setVisible(true);
					btnFinish.setVisible(true);
				}
			}
		});		
	}
		
	@UiField
	Button btnFinish;
	@UiHandler("btnFinish")
	void btnFinishClick(ClickEvent event) {
		this.btnTakeBattle.setEnabled(false);
		this.btnTakeDelivery.setEnabled(false);
		this.btnTakeEscort.setEnabled(false);
		this.btnFinish.setText("Creating Job Record...");
		this.btnFinish.setEnabled(false);
		
		mainForm.campaignService.CreateJob(job, new AsyncCallback<String>() {
    		public void onFailure(Throwable error) {
    			mainForm.handleError(error);
			}
			public void onSuccess(String result) {
				job.setId(result);
				job.setTaken(new Date());
				playerInfo.getJobs().add(job);				
				mainForm.showActivities();
			}
		});
		
		Window.open("https://groups.google.com/forum/#!newtopic/"+PlayerDTO.GROUP_NAME, "_blank", "");
	}
}